#include <QCoreApplication>
#include <iostream>
#include <cmath>
#include <initializer_list>

using namespace std;

int fact(int val)
{
    if (val < 0) {
        return -1;
    }
    int ret = 1;
    // 从 1连乘到 val
    for (int i = 1; i != val + 1; ++i) {
        ret *= i;
    }
    return ret;
}

void pr_6_4()
{
    cout << "请输入一个整数：" << endl;
    int num;
    cin >> num;
    cout << fact(num) << endl;
}

double MyAbs(double val)
{
    if (val < 0) {
        return val * -1;
    } else {
        return val;
    }
}

double MyAbs2(double val)
{
    return abs(val); // 通过调用 cmath库中的 abs函数计算绝对值
}

void pr_6_5()
{
    cout << "请输入一个数：" << endl;
    double val;
    cin >> val;
    cout << MyAbs(val) << endl;
    cout << MyAbs2(val) << endl;
}

int pr_6_7()
{
    static size_t ctr = 0;
    return ctr++; // 这种写法返回的是表达式的值,会从 0开始计数
}

int pr_6_10(int *x, int *y)
{
    int temp;
    temp = *x;
    *x = *y;
    *y = temp;

    return 0;
}

/**
 * @brief 返回 s中 c第一次出现的位置索引
 * @param s
 * @param c
 * @param occurs 统计 c出现的次数
 * @return
 */
string::size_type find_char(const string &s, char c, string::size_type &occurs)
{
    auto ret = s.size(); // 第一次出现的位置（如果有的话)
    occurs = 0; // 设置表示出现次数的形参的值
    for (decltype(ret) i = 0; i != s.size(); ++i) {
        if (s[i] == c) {
            if (ret == s.size()) {
                ret = i;  // 记录 c第一次出现的位置
            }
            ++occurs;  // 将出现的次数+1
        }
    }
    return ret; // 出现次数通过 occurs隐式返回
}

int pr_6_11(int &i)
{
    i = 0;
    return i;
}

void pr_6_12(int &x, int &y)
{
    int temp;
    temp = x;
    x = y;
    y = temp;
}

int pr_6_17_1(const string &s)
{
    if (s.empty()) {
        return -1;
    }

    for(char c : s) {
        if(islower(c)) {
            return 0;
        } else {
            return -1;
        }
    }
    return 0;
}

void pr_6_17_2(string &s)
{
    if (s.empty()) {
        return;
    }

    for (auto &c : s) {
       c = toupper(c);
    }
}

int pr_6_21(const int m, const int *n)
{
    return (m < *n) ? 1: -1;
}

void pr_6_22(int* &x, int* &y)
{
    int *tmp = x;
    x = y;
    y = tmp;
}

void error_msg(initializer_list<string> il)
{
    for (auto beg = il.begin(); beg != il.end(); ++beg) {
        cout << *beg << " ";
    }
    cout << endl;
}

int pr_6_27(initializer_list<int> il)
{
    int result = 0;
    for (auto beg = il.begin(); beg != il.end(); ++beg) {
        result += *beg;
    }
    cout << result;
    return result;
}

string make_plural(size_t ctr, const string &word, const string &ending = "s")
{
    return (ctr > 1) ? word + ending : word;
}

inline const string& shorterString(const string &s1, const string &s2)
{
    return s1.size() <= s2.size() ? s1 : s2;
}

void pr_6_47(vector<int> vInt, unsigned index)
{
    unsigned sz = vInt.size();
    // 设置在此处输出调试信息
#ifndef NDEBUG
    cout << "vector 对象的大小是: " << sz << endl;
#endif
    if (!vInt.empty() && index < sz) {
        cout << vInt[index] << endl;
        pr_6_47(vInt, index + 1);
    }
}

string::size_type sumLength(const string&, const string&);
string::size_type largeLength(const string&, const string&);
// 根据其形参的取值，getFcn函数返回指向sumLength或者 largeLength的指针
decltype(sumLength) *getFcn(const string&);

int func(int, int);
vector<decltype(func)*> vF;

// 加法
int OperatorPlus(int i1, int i2)
{
    return i1 + i2;
}

// 减法
int OperatorSubtract(int i1, int i2)
{
    return i1 - i2;
}

// 乘法
int OperatorMultiply(int i1, int i2)
{
    return i1 * i2;
}

// 除法
int OperatorDivide(int i1, int i2)
{
    return i1 / i2;
}

decltype(OperatorPlus) *p1 = OperatorPlus;
decltype(OperatorPlus) *p2 = OperatorSubtract;
decltype(OperatorPlus) *p3 = OperatorMultiply;
decltype(OperatorPlus) *p4 = OperatorDivide;
vector<decltype(OperatorPlus)*> vF1 = {p1, p2, p3, p4};

void Compute(int a, int b, int (*p)(int, int))
{
    cout << p(a, b) << endl;
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    for (auto p : vF1) {
        Compute(5, 10, p);
    }

    return a.exec();
}
